#include "server.h"

int fd_c_1;

int main(void) 
{
    // 将服务器做成守护进程
    // defend_pro();

    // 打开日志
    openlog("ikun", LOG_PID, LOG_DAEMON); // 打开日志，写入进程信息, 属于守护进程的日志

    // 创建套接字描述符
    int fd_s = socket(AF_INET, SOCK_STREAM, -1);
    if (fd_s < 0) {
        syslog(LOG_ERR, "get socket error");
        return -1;
    }
    // 绑定IP地址和端口号
    // 1. 确定IP地址，和端口号
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(11123); // 16位小端序转成大端序
    server.sin_addr.s_addr = inet_addr("192.168.3.18");
    // 2. 绑定操作
    if (bind(fd_s, (struct sockaddr *)&server, sizeof(server))) {
        syslog(LOG_ERR, "bind error");
        return -1;
    }
    printf("Debugs\n");
    // 监听，控制连接的主机的数量
    listen(fd_s, 8);

    // 创建用户注册表
    // 1. 打开数据库
    sqlite3 *ppdb; // 数据库句柄
    char *errmsg;
    int ret = sqlite3_open("uid.db", &ppdb);
    if (ret != SQLITE_OK) {
        syslog(LOG_ERR, "open error");
        return -1;
    }
    // 2. 创建用户注册表
    char sql[128] = "create table if not exists sign_in(user_uid char[50], "
                  "user_passwd char[50], user_fd int, user_status int);";
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK) {
        syslog(LOG_ERR, "create sign_in error");
        return -1;
    }

    // 3. 关闭数据库
    sqlite3_close(ppdb);

    /*
    // 3. 创建信号表
    bzero(sql, sizeof(sql));
    strcpy(sql, "create table if not exists _sig(sig char[20], from_uid char[50], to_uid char[50]);");
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK) {
        syslog(LOG_ERR, "create sig table error");
        return -1;
    }
    */

    // 等待连接
    // 准备接收主机端端口和IP地址
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    printf("Debug\n");

    // 接收
    while (1) {
        fd_c_1 = accept(fd_s, (struct sockaddr *)&client, &len); // 阻塞等待信号
        if (fd_c_1 < 0) {
            printf("see what's the frequence of the accept func\n");
            syslog(LOG_ERR, "accept error");
            return -1;
        }else{
            //
            if(fork() == 0){
                // 多并发进程，若是先fork再accept，while循环就会创建很多子进程，且这些子进程连接状态不定
                struct user my_info = {.fd = fd_c_1};
                INFO *info_recv = malloc(sizeof(INFO));  //只有创建成功了，才需要分配空间，服务器端需要用一个结构体来接受信息，同时用另一个结构体来转发信息
                // 只有登录成功的时候才会对该结构体赋值，且其他用到my_info的模块，都在登录成功之后，保证了使用my_info的正确性
                // 结构体初始化, 保存每次自己连接的fd_c_1
                char buf[512];
                while (1) {
                    // 获取信号
                    bzero(buf, sizeof(buf));
                    bzero(info_recv, sizeof(INFO)); //清空info_recv，用于接受新的数据
                    int ret = recv(my_info.fd, buf, sizeof(buf), 0); // 阻塞接收信号
                    printf("recv buf = %s\n", buf);
                    if (ret < 0) {
                        syslog(LOG_ERR, "recv sig error");
                        // perror("recv");
                        return -1;
                    }
                    //如果ret不小于零，则可以开始解析buf数据包
                    json_To_Info(buf, info_recv);
                    //printf("server buf = %s\n", buf);
                    //根据信号，调用相应的相应模块，处理结束后等待下一次接受信号
                    switch (info_recv->cmd) {
                        case SIGNUP:  //登录
                            printf("xxxxxxx");
                            log_in(info_recv);
                            break;
                        case LOGIN:  //登录
                            printf("yyyyyyyy\n");
                            log_in(info_recv);
                            bzero(buf, sizeof(buf));
                            info_To_Json(info_recv, buf);
                            printf("send info_recv buf = %s\n", buf);
                            ret = send(info_recv->fd, buf, strlen(buf), 0);
                            printf("send ret = %d\n", ret);
                            if (ret < 0) {
                                perror("send??");
                                return 0;
                            }
        //sig_send(info->fd, "log ok"); // 向客户端发送登录成功信�?
                            break;
                    }
                }
            }
        }
    }

    // 关闭日志
    closelog();

    return 0;
}
